/**
 * Easy Descriptor 库的核心类型定义
 * 
 * 该模块包含整个库中使用的基础类型和接口，
 * 包括模型定义、字段选项和装饰器类型。
 */
import {FormDataTypeEnum, FormTypeEnum, InputTypeEnum} from "../enums";

/**
 * 从 Axios 描述符模块重新导出类型
 */
export type * from '../descriptor/AxiosDescriptor/types'

/**
 * 表示模型和字段的唯一标识符类型
 * 可以是字符串或符号
 */
export type DataKey = string | symbol

/**
 * 所有描述符模型应继承的基础模型类
 * 
 * @template T - 模型类型本身（用于自引用类型）
 * @template TB - 与此模型关联的字段选项类型
 */
//export default class IBaseModel<T extends IBaseModel<T> = IBaseModel<any>, TB extends ExtFieldOption = FieldOption> {

// export default class IBaseModel<T extends IBaseModel<T>, TB extends FieldOption<T> = FieldOption<T>> {
export interface IBaseModel<T extends IBaseModel<T>> {
    // $TB?: TB
}

/**
 * 从字符串/数字枚举中提取枚举键的工具类型
 * 
 * @template T - 映射枚举类型（字符串或数字）
 */
export type EnumTypes<T extends string | number> = keyof { [k in T]: unknown }

export declare type IFormData<T extends IBaseModel<T>> = Record<string, any> & {
    [key in keyof T]?: T[key]
}
export declare type FormType = EnumTypes<FormTypeEnum>
export declare type FormDataType = EnumTypes<FormDataTypeEnum>
export declare type InputType = EnumTypes<InputTypeEnum>

// 让处理器与具体模型类型解耦，避免函数参数逆变导致的泛型递归不兼容问题
export type FieldAttrHandler<P = any> = <T extends IBaseModel<T>>(formData: IFormData<T>, formType?: FormType) => P

export type FieldHiddenType = boolean | ('list' | 'form' | 'query' | 'edit' | 'add' | 'view')[]
export type FieldDisabledType = boolean | ('form' | 'edit' | 'add' | 'editTable')[]

type ModelStateRequiredAttr<T extends IBaseModel<T>, P> = { [key in keyof Required<T>]: P } | Record<string, P>
type ModelStatePartialAttr<T extends IBaseModel<T>, P> = { [key in keyof Partial<T>]: P } | Record<string, P>
type ModelField<T extends IBaseModel<T>> = ModelStateRequiredAttr<T, string>

type BooleanFlag = string | 'hidden' | 'dict'

/**
 * 包含所有可能字段配置选项的扩展字段选项接口
 * 
 * 这是所有字段选项应继承的基础接口
 */
// export interface ExtFieldOption<T extends IBaseModel<T> = IBaseModel<any>> extends Record<string, any> {
//     key: DataKey;
//     label?: string;
//     hidden?: FieldHiddenType;
//     hiddenHandler?: FieldAttrHandler<boolean>;
//     disabled?: FieldDisabledType;
//     disabledHandler?: FieldAttrHandler<boolean>;
//     dataType?: FormDataType;
//     inputType?: InputType;
//     inputProps?: Record<string, any>;
//     queryInputProps?: Record<string, any>;
//     booleanFlags?: BooleanFlag[];
//     dict?: string;
//     formSpan?: number;
//     render?: (data: T) => any;
// }

export type FieldOption<T extends IBaseModel<T> = IBaseModel<any>> = Record<string, any> & {
    key: DataKey;
    label?: string;
    hidden?: FieldHiddenType;
    hiddenHandler?: FieldAttrHandler<boolean>;
    disabled?: FieldDisabledType;
    disabledHandler?: FieldAttrHandler<boolean>;
    dataType?: FormDataType;
    inputType?: InputType;
    inputProps?: Record<string, any>;
    queryInputProps?: Record<string, any>;
    booleanFlags?: BooleanFlag[];
    dict?: string;
    formSpan?: number;
    render?: (data: T) => any;
}

export type PartialFieldOption<T extends IBaseModel<T>> = Partial<FieldOption<T>>


export type TreeField<T extends IBaseModel<T>> = {
    pid?: 'parentId' | keyof ModelField<T>
    children?: 'children' | keyof ModelField<T>
}

export declare type ModelParams<T extends IBaseModel<T>> = Partial<EzModelOptions<T>>

/**
 * 创建新模型描述符的配置选项
 * 
 * @template T - 此配置适用的模型类型
 */
export declare type EzModelOptions<T extends IBaseModel<T>> = {
    modelKey?: DataKey
    name: string
    desc?: string
    api: string
    perms: string | boolean
    fields: ModelStatePartialAttr<T, FieldOption<T>>
    tree?: true | TreeField<T>
}

// export declare type EzModelPool = {
//     [key: DataKey]: EzModelOptions
// }
export declare type DictDecoratorType = (dict?: string) => PropertyDecorator
export declare type HiddenDecoratorType = (
    hiddenType?: FieldHiddenType,
    hiddenHandler?: FieldAttrHandler<boolean>
) => PropertyDecorator
export declare type DisabledDecoratorType = (
    disabledType?: FieldDisabledType,
    disabledHandler?: FieldAttrHandler<boolean>
) => PropertyDecorator
export declare type DataTypeDecoratorType = (dataType?: FormDataType, inputType?: InputType) => PropertyDecorator

export interface BaseModelConstructor<T extends IBaseModel<T> = IBaseModel<any>> extends Function {
    new(...args: any[]): T
    $OPTS?: EzModelOptions<T>
}

/**
 * 带有额外静态装饰器方法的字段装饰器接口
 * 
 * @template T - 此装饰器适用的模型类型
 */
export interface FieldDecorator<T extends IBaseModel<T> = IBaseModel<any>, OPT extends FieldOption<T> = FieldOption<T>> {
    <T extends IBaseModel<T>>(label?: string | Partial<OPT>, option?: Partial<OPT>): PropertyDecorator

    Hidden: HiddenDecoratorType
    Dict: DictDecoratorType
    Disabled: DisabledDecoratorType
    DataType: DataTypeDecoratorType
}
